﻿namespace SimpleX.RBAC
{
    public class RoleService : DbRepository<SysRole>, IRoleService
    {
        private readonly IRelationService _relationService;
        private readonly ICacheService _cacheService;

        public RoleService(IRelationService relationService,
            ICacheService cacheService)
        {
            _relationService = relationService;
            _cacheService = cacheService;
        }

        public async Task Add(RoleAddInput input)
        {
            var exist = await GetFirstAsync(x => x.Name == input.Name);
            if (exist != null)
            {
                Unify.SetError($"角色已经存在");
                return;
            }
            var sysRole = input.Adapt<SysRole>();//实体转换
            await InsertAsync(sysRole);
        }

        public async Task Delete(List<BaseIdInput> input)
        {
            var ids = input.Select(it => it.Id).ToList();
            if (ids.Count > 0)
            {
                //删除用户的接口权限缓存
                _cacheService.Remove(CacheConst.Cache_UserRelation);

                var result = await itenant.UseTranAsync(async () =>
                {
                    await DeleteByIdsAsync(ids.Cast<object>().ToArray());//删除角色
                    var relationRep = ChangeRepository<DbRepository<SysRelation>>();//切换仓储
                    //用户有多少角色
                    await relationRep.DeleteAsync(it => ids.Contains(it.TargetId) && it.Category == CateGoryConst.Relation_SYS_USER_HAS_ROLE);
                    //角色有多少菜单
                    await relationRep.DeleteAsync(it => ids.Contains(it.ObjectId) && it.Category == CateGoryConst.Relation_SYS_ROLE_HAS_MENU);
                });
                if (result.IsSuccess)//如果成功了
                {
                }
                else
                {
                    throw result.ErrorException;
                }
            }
        }

        public async Task Edit(RoleEditInput input)
        {
            var exist = await GetFirstAsync(x => x.Name == input.Name);
            if (exist != null && exist.Id != input.Id)
            {
                Unify.SetError($"角色已经存在");
                return;
            }
            var sysRole = input.Adapt<SysRole>();//实体转换
            await UpdateAsync(sysRole);//更新角色
        }

        public async Task<List<SysRole>> GetRoleListByUserId(string userId)
        {
            List<SysRole> cods = new List<SysRole>();//角色代码集合
            var roleList = await _relationService.GetRelationListByObjectIdAndCategory(userId, CateGoryConst.Relation_SYS_USER_HAS_ROLE);//根据用户ID获取角色ID
            var roleIdList = roleList.Select(x => x.TargetId).ToList();//角色ID列表
            if (roleIdList.Count > 0)
            {
                cods = await GetListAsync(it => roleIdList.Contains(it.Id));
            }
            return cods;
        }

        public async Task GrantMenu(GrantMenuInput input)
        {
            var relationRoles = new List<SysRelation>();//要添加的角色资源和授权关系表

            foreach (var item in input.GrantInfoList)
            {
                relationRoles.Add(new SysRelation
                {
                    ObjectId = input.Id,
                    TargetId = item.MenuId,
                    Category = CateGoryConst.Relation_SYS_ROLE_HAS_MENU,
                    ExtJson = item.ButtonInfo.ToJson(),
                });
            }

            //删除用户的接口权限缓存
            _cacheService.Remove(CacheConst.Cache_UserRelation);

            //事务
            var result = await itenant.UseTranAsync(async () =>
            {
                var relationRep = ChangeRepository<DbRepository<SysRelation>>();//切换仓储
                //删除 角色有多少菜单
                await relationRep.DeleteAsync(it => it.ObjectId == input.Id && it.Category == CateGoryConst.Relation_SYS_ROLE_HAS_MENU);
                //添加新的
                await relationRep.InsertRangeAsync(relationRoles);
            });
            if (result.IsSuccess)//如果成功了
            {
            }
            else
            {
                throw result.ErrorException;
            }
        }

        public async Task<RoleOwnResourceOutput> OwnResource(BaseIdInput input)
        {
            var roleOwnResource = new RoleOwnResourceOutput() { Id = input.Id };
            List<RelationRoleMenu> GrantInfoList = new List<RelationRoleMenu>();

            var relations = await _relationService.GetRelationListByObjectIdAndCategory(input.Id, CateGoryConst.Relation_SYS_ROLE_HAS_MENU);

            foreach (var item in relations)
            {
                GrantInfoList.Add(new RelationRoleMenu
                {
                    MenuId = item.TargetId,
                    ButtonInfo = item.ExtJson.ToObject<List<string>>()
                });
            }

            roleOwnResource.GrantInfoList = GrantInfoList;
            return roleOwnResource;
        }

        public async Task<SqlSugarPagedList<SysRole>> Page(RolePageInput input)
        {
            var query = Context.Queryable<SysRole>()
                             .WhereIF(!string.IsNullOrEmpty(input.SearchKey), it => it.Name.Contains(input.SearchKey))//根据关键字查询
                             .OrderByIF(!string.IsNullOrEmpty(input.SortField), $"{input.SortField} {input.SortOrder}")
                             .OrderBy(it => it.SortCode);//排序
            var pageInfo = await query.ToPagedListAsync(input.Current, input.Size);//分页
            return pageInfo;
        }

        public async Task<List<SysRole>> RoleSelector(string searchKey)
        {
            var query = Context.Queryable<SysRole>()
                             .WhereIF(!string.IsNullOrEmpty(searchKey), it => it.Name.Contains(searchKey))//根据关键字查询
                             .OrderBy(it => it.Name);//排序
            return await query.ToListAsync();
        }
    }
}